package com.xxwy.webSocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @author wy
 * @date 2020/3/6 13:59
 */
public class NettyServer {
  public static void main(String[] args) {
    NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
    NioEventLoopGroup workerGroup = new NioEventLoopGroup();

    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .handler(new LoggingHandler(LogLevel.INFO))
        .childHandler(new ChannelInitializer<SocketChannel>() {

          @Override
          protected void initChannel(SocketChannel socketChannel) throws Exception {
            //像管道加入编解码器
            ChannelPipeline pipeline = socketChannel.pipeline();
            pipeline.addLast("HttpServerCodec", new HttpServerCodec());

            //是以块方式写，添加ChunkedWriteHandler处理器
            pipeline.addLast(new ChunkedWriteHandler());
            /**
             * http数据在传输过程中是分段，httpObjectAggregator,就可以将多个段聚合起来
             * 当浏览器发送大量数据时，数据就会分段，发出多次http请求
             */
            pipeline.addLast(new HttpObjectAggregator(8192));

            /**
             * 对应webSocket,数据是以帧的形式传递
             * 可以看到WebSocketFrame 下面的六个子类
             * ws://localhost/6666/hi 表示请求的uri
             * WebSocketServerProtocolHandler：核心功能将http协议升级为ws协议,保持长连接
             *
             * 自定义的handler，处理业务逻辑
             */
            pipeline.addLast(new WebSocketServerProtocolHandler("/hi"));
            pipeline.addLast(new MyWebSocketFrameHandler());

          }
        });

    try {
      ChannelFuture future = serverBootstrap.bind(6666).sync();
      System.out.println("ok " + future.channel().localAddress());
      future.channel().closeFuture().sync();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
    }
  }
}

